/**
 * @Copyright：<a href="www.wisesoft.net.cn">四川川大智胜系统集成有限公司</a>
 * @Author: <a href="mailto:fxsen@foxmail.com">Fxsen</a>
 * @CreateTime: 2022年08月03日  17:21
 */
package com.fxsen.commons.utils;

import com.fxsen.commons.core.base.common.entity.JwtUser;
import com.fxsen.commons.core.exception.NotAuthorizedException;
import io.jsonwebtoken.*;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.util.Date;
import java.util.Map;

/**
 * jwt工具类
 *@Author: <a href="mailto:fxsen@foxmail.com">Fxsen</a>
 *@CreateTime: 2022年08月03日  17:21
 */
@Component
public class JwtUtils {
    /**
     * 租户id的key
     */
    public final static String JWT_LEASE_ID = "leaseId";
    /**
     * jwt的key,也是前端放在header里的key
     */
    public static String JWT_HEADER_KEY;
    /**
     * jwt x_token生成的秘钥
     */
    public static String JWT_SECRET;
    /**
     * jwt获取过期时间的key,分钟
     */
    public static long JWT_EXP_TIME;
    /**
     * x_token不对,或者过期,跳转的登录页面url
     */
    public static String JWT_LOGIN_URL;

    @Value("${project-config.jwt.headerKey}")
    public void setJwtHeaderKey(String jwtHeaderKey) {
        JwtUtils.JWT_HEADER_KEY = jwtHeaderKey;
    }
    @Value("${project-config.jwt.secret}")
    public void setJwtSecret(String jwtSecret) {
        JwtUtils.JWT_SECRET = jwtSecret;
    }
    @Value("${project-config.jwt.expTime}")
    public void setJwtExpTime(long jwtExpTime) {
        JwtUtils.JWT_EXP_TIME = jwtExpTime;
    }
    @Value("${project-config.jwt.secret}")
    public void setJwtLoginUrl(String jwtLoginUrl) {
        JwtUtils.JWT_LOGIN_URL = jwtLoginUrl;
    }
    /**
     * jwt获取userId的key
     */
    public final static String JWT_USER_ID = "userId";
    /**
     * jwt获取username的key
     */
    public final static String JWT_USER_NAME = "userName";
    /**
     * jwt获取部门id的key
     */
    public final static String JWT_DEPARTMENT_ID = "departmentId";
    /**
     * jwt获取部门ids的key
     */
    public final static String JWT_DEPARTMENT_IDS = "departmentIds";
    /**
     * jwt获取登录设备uuid的key
     */
    public final static String JWT_DEVICE_UUID = "deviceId";
    /**
     * jwt拦截的路径前缀
     * 由于在注解中使用，需要编译时常量
     */
    public final static String JWT_PATH = "/api/";
    /**
     * 根据参数返回token
     */
    public static String buildToken(JwtUser jwtUser) {
        String accessToken = Jwts.builder().setHeaderParam("alg", "HS256")
                .setHeaderParam("typ", "JWT")
                .setIssuedAt(new Date())
                .setExpiration(new Date(System.currentTimeMillis() + JWT_EXP_TIME))
                .claim("jwtUser", jwtUser)
                .signWith(SignatureAlgorithm.HS256, JWT_SECRET).compact();
        return accessToken;
    }

    public static JwtUser getParamByToken(String token) {
        if(token == null) {
            return new JwtUser();
        }
        JwtParser io = Jwts.parser().setSigningKey(JWT_SECRET);
        try {
            Jws<Claims> claims = io.parseClaimsJws(token);
            return BeanUtils.mapToObj((Map<String,Object>) claims.getBody().get("jwtUser"), JwtUser.class);
        }catch (Exception e){
            throw new NotAuthorizedException("当前账号已过期，请重新登录~\uD83D\uDE0A");
        }
    }
    public static void verifyToken(String token){
        if(token == null) {
            throw new NotAuthorizedException("当前账号已过期，请重新登录~\uD83D\uDE0A");
        }
        try {
            Jwts.parser().setSigningKey(JWT_SECRET).parseClaimsJws(token);
        }catch (Exception e){
            throw new NotAuthorizedException("当前账号已过期，请重新登录~\uD83D\uDE0A");
        }
    }
}
